<?php
namespace Kuoqi\DbDriver\Sql;
class Where{
	
	static protected $code2code = array(
		'LT'=>'`%s` < "%s"',
		'GT'=>'`%s` > "%s"',
		'EQ'=>'`%s` = "%s"',
		'NE'=>'`%s` != "%s"',
		'NEQ'=>'`%s` != "%s"',
		'>'=>'`%s` > "%s"',
		'<'=>'`%s` < "%s"',
		'='=>'`%s` = "%s"',
		'>='=>'`%s` >= "%s"',
		'<='=>'`%s` <= "%s"',
		'<>'=>'`%s` <> "%s"',
		'IN'=>'`%s` IN (%s)',
		'NOTIN'=>'`%s` NOT IN (%s)',
		'LIKE'=>'`%s` LIKE "%s"',
		'NOTLIKE'=>'`%s` NOT LIKE "%s"',
		'BETWEEN'=>'`%s` BETWEEN %s AND %s',
		'NOTBETWEEN'=>'`%s` NOT BETWEEN %s AND %s',
		'!='=>'`%s` != %s',
	);
	
	/**
	 * 尝试匹配字段
	*/
	static function matchCode($code){
		$code = strtoupper($code);
		if(isset(self::$code2code[$code])){
			return self::$code2code[$code];
		}else{
			throw new \Kuoqi\Error('关键词为'.$code.'的匹配关系待开发');
		}	
	}
	
	//尝试自动处理where key
	static function matchKey($name){
		$brr = explode('.',$name);
		if(count($brr)>=2){
			$name = implode('`.`',$brr);
		}	
		return $name;
	}
	
	public $condition = 'and';//总的condition
	public $factor = null;//初始化发布的内容
	public $isDebug = false;
	
	public $fragment = array();//存储那些片段的信息
	
	public function __construct(){
		
		
	}
	
	//初始化输入
	public function input($factor){
		$this->factor = $factor;
		$this->initFragment($this->factor);
	}
	
	//输出处理区域
	//是否携带WHERE字段
	public function output($withCode = true,$isSub = false){
		//hash判定为键值对	
		//string判定为直接的字符串
		$str = '';
		foreach($this->fragment as $v){
			switch($v['format']){
				case 'string':$tmp = $this->outputString($v['params']);break;
				case 'array':$tmp = $this->outputArray($v['params']);break;
				case 'object':$tmp = $this->outputObject($v['params']);break;
				default:throw new \Kuoqi\Error('暂不支持条件'.$v['format'].'的显示');
			}
			if($str){
				$str .= ' '.$this->condition .' '. $tmp;
			}else{
				$str .= $tmp;	
			}
		}
		return $withCode?'WHERE ('.$str.')':'('.$str.')';
	}
		
	//对string的输出绑定
	public function outputString($str){
		return $str;	
	}
	
	//对array的输出绑定
	public function outputArray($arr){
		//判定$arr[1]是否有.
		return sprintf(self::matchCode($arr[1]),self::matchKey($arr[0]),$arr[2]);
	}
	
	//对于对象的输出绑定
	public function outputObject($obj){
		return $obj->output(false);
	}
	
	
	
	
	//输入处理区域
	//针对每次输入的片段的基础初始化
	public function initFragment($factor){
		//首先判定是数组还是字符串
		if(is_array($factor)){
			//判定为数组，执行数组的初始化	
			//判定是否为索引数组
			foreach($factor as $k=>$v){
				if(is_string($k)){
					//非索引数组-关联数组
					//优先索检$k的值
					if($k=='_complex'){
						//索检到复杂结构
						$condition = $v[0];
						unset($v[0]);
						$this->fragment[] = $this->flushTofragment($condition,'complex',$v,true);
					}elseif(is_array($v)){
						//判断子对象是否为多个
						//判定是两个还是其他
						if(count($v)==2){
							$this->fragment[] = $this->flushTofragment($this->condition,'array',array($k,$v[0],$v[1]));
						}else{
							throw new \Kuoqi\Error('暂不支持该条件的查询，请站长补充');
						}
					}else{
						//这是v为非数组的情况，这个情况，直接判定为等于
						$this->fragment[] = $this->flushTofragment($this->condition,'array',array($k,'=',$v));	
					}
				}else{
				    //直接判定第一级是否为复杂模式
                    if(isset($v[0])&&($v[0]=='_complex')){
                        if((isset($v[1])&&is_string($v[1]))){
                            $condition = $v[1];
                            unset($v[0],$v[1]);
                        }else{
                            $condition = 'and';
                            unset($v[0]);
                        }
                        sort($v);
                        $this->fragment[] = $this->flushTofragment($condition,'complex',$v);
                    }elseif(count($v)==3){
						$this->fragment[] = $this->flushTofragment($this->condition,'array',array($v[0],$v[1],$v[2]));
					}else{
					    //todo--这是其他情况的
						//索引数组
						throw new \Kuoqi\Error($v);
					}
				}
			}
		}elseif(is_string($factor)){
			//判定为字符串，执行字符串的初始化
			//直接使用该字符串
			$this->fragment[] = $this->flushTofragment($this->condition,'string',$factor);
			
			
		}else{
			throw new \Kuoqi\Error('暂不支持该where计算公式['.string($factor).']');
		}
	}
	
	
	//将信息冲刷为fragment对象
	public function flushTofragment($condition,$format,$params,$isDebug = false){


		//判定format为对象的操作
		if($format=='complex'){
			//判定为复杂条件
			$where = new self();
			$where->condition = $condition;
			//$where->condition = 'test';
			$where->input($params);
			return array('condition'=>$condition,'format'=>'object','params' => $where);
		}else{
			//做最终判定,判定特殊格式
			$cn = explode('|',$params[0]);
			if(count($cn)>1){
				//这个情况相对比较复杂了，需要新申请一个where对象来做这个
				$cache = array();
				foreach($cn as $n){
					$cache[] = array($n,$params[1],$params[2]);	
				}
				$where = new self();
				$where->condition = 'or';
				$where->input($cache);
				//返回一个对象
				return array('condition'=>'and','format'=>'object','params' => $where);
			}
			return array('condition'=>$condition,'format'=>$format,'params' => $params);
		}
	}
	
}